﻿#include "RXShadowNode.h"
#include "RXAspectEngine.h"
#include "RXAspect.h"

RXAspect::RXAspect()
{
	engine = NULL;
}

void RXAspect::SetAspectInfo(const RXAspectInfo & info)
{
	this->info = info;
}

const RXAspectInfo & RXAspect::GetAspectInfo() const
{
	return info;
}

void RXAspect::PostToFrontNode(RXECSDef::NodeId nodeId, ThreadSafe::Event * event)
{
	if (engine) {
		engine->PostToFrontNode(nodeId, event);
	}
}

void RXAspect::RegisterAspectService(const RXECSDef::RXAspectServiceID& name, RXAspectService * service)
{
	m_services[name].reset(service);
}

void RXAspect::UnRegisterAspectService(const RXECSDef::RXAspectServiceID& name)
{
	m_services.erase(name);
}

RXAspectService * RXAspect::AcquireAspectService(const RXECSDef::RXAspectServiceID& name)
{
	return engine->AcquireAspectService(name);
}

void RXAspect::OnNewNodeSpawned(RXECSDef::NodeCreationInfoPtr ret)
{
}

void RXAspect::OnNodeDestoried(RXECSDef::NodeId id)
{
}

void OnNodeDestoried(RXECSDef::NodeId id)
{

}

void RXAspect::RegisterNodeClass(const MetaInfo & m)
{
	engine->RegisterNodeType(m);
}

void RXAspect::HandleNodeSpawnEvent(RXECSDef::NodeCreationInfoPtr ret)
{
	//产生后端节点
	for (auto &j : m_factorys) {
		if (j.meta == ret->meta || j.meta.IsBaseOf(ret->meta)) {
			auto node = j.factory->CreateNode();
			node->InitNode(*ret);
			j.factory->RegisterNode(node);
		}
	}
}

void RXAspect::HandleNodePropertyChangeEvent(RXECSDef::NodePropertyChangeEventPtr ret)
{
	for (auto &j : m_factorys) {
		auto node = j.factory->GetNode(ret->id);
		if (node) {
			node->HandlePropertyChange(*ret);
		}
	}
}

void RXAspect::HandleNodeDestoryEvent(RXECSDef::NodeId ret)
{
	for (auto &j : m_factorys) {
		j.factory->ReleaseNode(ret);
	}

	OnNodeDestoried(ret);
}

void RXAspect::HandleNodePostEvent(RXECSDef::NodeId id, ThreadSafe::Event * e)
{
	for (auto &j : m_factorys) {
		auto node = j.factory->GetNode(id);
		if (node) {
			node->HandleFrontNodeEvent(e);
		}
	}
}

void RXAspect::RegisterShadowFactoryImp(const MetaInfo & meta, ShadowNodeFactoryBase * factory)
{
	NodeFactoryInfo info;
	info.meta = meta;
	info.factory = ShadowNodeFactoryPtr(factory);

	m_factorys.push_back(info);
}

void ShadowNodeFactoryBase::ReleaseNode(RXECSDef::NodeId id)
{
	auto p = m_nodeMap[id];
	if (p) {
		delete p;
		m_nodeMap.erase(id);
	}
}

ShadowNodeFactoryBase::~ShadowNodeFactoryBase()
{
	for (auto i : m_nodeMap) {
		delete i.second;
	}
}

RXShadowNode * ShadowNodeFactoryBase::GetNode(RXECSDef::NodeId id)
{
	if (m_nodeMap.count(id)) {
		return m_nodeMap.at(id);
	}

	return NULL;
}

void ShadowNodeFactoryBase::Foreach(const std::function<bool(RXShadowNode*)>& pred)
{
	for (auto &i : m_nodeMap) {
		bool is_continue = pred(i.second);
		if (!is_continue) {
			return;
		}
	}
}

int ShadowNodeFactoryBase::GetSize() const
{
	return m_nodeMap.size();
}

void ShadowNodeFactoryBase::RegisterNode(RXShadowNode * node)
{
	m_nodeMap[node->GetNodeId()] = node;
}

RXAspectInfo::RXAspectInfo()
{
}

RXAspectInfo::RXAspectInfo(RXECSDef::RXAspectID name, const std::vector<RXECSDef::RXAspectID>& rely)
{
	this->Name = name;
	this->RelyAspect = rely;
}

const RXECSDef::RXAspectID & RXAspectInfo::GetName() const
{
	return Name;
}

const std::vector<RXECSDef::RXAspectID>& RXAspectInfo::GetRelyAspects() const
{
	return RelyAspect;
}
